home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Applications
/
Python 1.3.3
/
Python 133 68K
/
Lib
/
img
/
imgjpeg.py
< prev
next >
Wrap
Text File
|
1996-05-20
|
4KB
|
129 lines
"""A module that reads JPEG files using the SGI Compression Library.
This module should only be used in a python-interpreter with the cl
module configured, otherwise the builtin imgjpeg module is better."""
import cl
from imgformat import rgb, rgb_b2t, xrgb8, xrgb8_b2t, xgrey, xgrey_b2t, \
rgb8, rgb8_b2t, grey, grey_b2t
error = 'imgpjpeg.error'
class reader:
def __init__(self, filename):
self._filename = filename
self._file = f = open(filename, 'rb')
header = f.read(16)
scheme = cl.QueryScheme(header)
self._decompressor = decomp = cl.OpenDecompressor(scheme)
size = cl.QueryMaxHeaderSize(scheme)
if size > len(header):
header = header + f.read(size - len(header))
headersize = decomp.ReadHeader(header)
self.width = decomp.GetParam(cl.IMAGE_WIDTH)
self.height = decomp.GetParam(cl.IMAGE_HEIGHT)
self.format_choices = rgb, xrgb8, xrgb8_b2t, xgrey
if not hasattr(cl, 'JPEG_SOFTWARE'):
self.format_choices = self.format_choices + (rgb_b2t, xgrey_b2t)
self.format = rgb # default format
def args(self):
return self.__dict__
def read(self):
if self.format in (rgb, rgb_b2t):
original_format = cl.RGBX
elif self.format in (xrgb8, xrgb8_b2t, rgb8, rgb8_b2t):
original_format = cl.RGB332
elif self.format in (xgrey, xgrey_b2t, grey, grey_b2t):
original_format = cl.GRAYSCALE
else:
raise error, 'Unknown format'
if self.format in (rgb_b2t, xrgb8_b2t, xgrey_b2t, rgb8_b2t, grey_b2t):
orientation = cl.BOTTOM_UP
else:
orientation = cl.TOP_DOWN
width = self.width
if original_format == cl.RGB332 and hasattr(cl, 'JPEG_SOFTWARE'):
# Irix 5.3 uses more buffer than it should, so allocate some extra
width = (width + 3) & ~3
bbp = cl.BytesPerPixel(original_format)
params = [cl.ORIGINAL_FORMAT, original_format,
cl.ORIENTATION, orientation,
cl.FRAME_BUFFER_SIZE, width * self.height * bbp]
self._decompressor.SetParams(params)
self._file.seek(0)
data = self._decompressor.Decompress(1, self._file.read())
if hasattr(cl, 'JPEG_SOFTWARE'):
if self.width & 1:
# Irix 5.3 has difficulty with odd-width images. It
# rounds the width down to an even number, so we
# double the right-most pixel so that the image gets
# the original width again.
rv = ''
w = (self.width - 1) * bbp
for i in range(0, self.height * w, w):
rv = rv + data[i:i+w] + data[i+w-bbp:i+w]
return rv
# only return the image, not the extra space
return data[:self.width*self.height*bbp]
else:
return data
def write(self, data):
raise error, 'Cannot write() to reader'
class writer:
def __init__(self, filename):
self._filename = filename
self.format_choices = rgb, rgb_b2t, xrgb8, xrgb8_b2t, xgrey, xgrey_b2t
self.format = rgb
def args(self):
return self.__dict__
def _get(self, attr):
try:
return getattr(self, attr)
except AttributeError:
raise error, "Required attribute '%s' missing"%attr
def read(self):
raise error, 'Cannot read() from writer'
def write(self, data):
width = self._get('width')
height = self._get('height')
format = self._get('format')
if format in (rgb, rgb_b2t):
original_format = cl.RGBX
elif format in (xrgb8, xrgb8_b2t):
original_format = cl.RGB332
elif format in (xgrey, xgrey_b2t):
original_format = cl.GRAYSCALE
else:
raise error, 'Unknown format'
if format in (rgb_b2t, xrgb8_b2t, xgrey_b2t):
orientation = cl.BOTTOM_UP
else:
orientation = cl.TOP_DOWN
if width * height * cl.BytesPerPixel(original_format) != len(data):
raise error, 'Incorrect datasize'
params = [cl.ORIGINAL_FORMAT, original_format,
cl.ORIENTATION, orientation,
cl.IMAGE_WIDTH, width,
cl.IMAGE_HEIGHT, height]
try:
quality = self.quality
except AttributeError:
pass
else:
params.append(cl.QUALITY_FACTOR)
params.append(quality)
compressor = cl.OpenCompressor(cl.JPEG)
compressor.SetParams(params)
data = compressor.Compress(1, data)
file = open(self._filename, 'wb')
file.write(data)